package javax.obex;
/**
 * The <code>ClientSession</code> interface provides methods for OBEX requests.
 *  This interface provides a way to define headers for any OBEX operation.
 *  OBEX operations are CONNECT, SETPATH, PUT, GET and DISCONNECT.  For PUTs and
 *  GETs, this interface will return a <code>javax.obex.Operation</code> object
 *  to complete the operations.  For CONNECT, DISCONNECT, and SETPATH operations,
 *  this interface will complete the operation and return the result in a
 *  <code>HeaderSet</code> object.
 *  <P>
 *  <STRONG>Connection ID and Target Headers</STRONG>
 *  <P>
 *  According to the IrOBEX specification, a packet may not contain a Connection
 *  ID and Target header.  Since the Connection ID header is managed by the
 *  implementation, it will not send a Connection ID header if a Connection ID
 *  was specified in a packet that has a Target header.  In other words, if an
 *  application adds a Target header to a <code>HeaderSet</code> object used
 *  in an OBEX operation and a Connection ID was specified, no Connection ID
 *  will be sent in the packet containing the Target header.
 *  <P>
 *  <STRONG>CREATE-EMPTY and PUT-DELETE Requests</STRONG>
 *  <P>
 *  To perform a CREATE-EMPTY request, the client must call the
 * <code>put()</code> method.  With the <code>Operation</code> object returned,
 *  the client must open the output stream by calling
 *  <code>openOutputStream()</code> and then close the stream by calling
 *  <code>close()</code> on the <code>OutputStream</code> without writing
 *  any data.  Using the <code>DataOutputStream</code> returned from
 *  <code>openDataOutputStream()</code> works the same way.
 *  <P>
 *  There are two ways to perform a PUT-DELETE request.  The
 *  <code>delete()</code> method is one way to perform a PUT-DELETE request.
 *  The second way to perform a PUT-DELETE request is by calling
 *  <code>put()</code> and never calling <code>openOutputStream()</code> or
 *  <code>openDataOutputStream()</code> on the <code>Operation</code> object
 *  returned from <code>put()</code>.
 *  <P>
 *  <STRONG>PUT example</STRONG>
 *  <P>
 *  <PRE>
 *  void putObjectViaOBEX(ClientSession conn, HeaderSet head, byte[] obj)
 *     throws IOException {
 * 
 *      // Include the length header
 *      head.setHeader(HeaderSet.LENGTH, new Long(obj.length));
 * 
 *     // Initiate the PUT request
 *      Operation op = conn.put(head);
 * 
 *      // Open the output stream to put the object to it
 *      OutputStream out = op.openOutputStream();
 * 
 *      // Send the object to the server
 *      out.write(obj);
 * 
 *      // End the transaction
 *      out.close();
 *      op.close();
 *  }
 *  </PRE>
 *  <P>
 *  <STRONG>GET example</STRONG>
 *  <P>
 *  <PRE>
 *  byte[] getObjectViaOBEX(ClientSession conn, HeaderSet head) throws IOException {
 * 
 *      // Send the initial GET request to the server
 *      Operation op = conn.get(head);
 * 
 *      // Get the object from the input stream
 *      InputStream in = op.openInputStream();
 * 
 *      ByteArrayOutputStream out = new ByteArrayOutputStream();
 *      int data = in.read();
 *      while (data != -1) {
 *          out.write((byte)data);
 *          data = in.read();
 *      }
 * 
 *      // End the transaction
 *      in.close();
 *      op.close();
 * 
 *      byte[] obj = out.toByteArray();
 *      out.close();
 * 
 *      return obj;
 *  }
 *  </PRE>
 */
public interface ClientSession extends javax.microedition.io.Connection {

	/**
	 * Sets the {@link Authenticator} to use with this connection. The {@link Authenticator} 
	 * allows an application to respond to authentication challenge and authentication 
	 * response headers. If no {@link Authenticator} is set, the response to an 
	 * authentication challenge or authentication response header is implementation 
	 * dependent.
	 * 
	 * @param auth the {@link Authenticator} to use for this connection
	 * @throws java.lang.NullPointerException if {@code auth} is {@code null}
	 */
	public void setAuthenticator(Authenticator auth);
	
	/**
	 * Creates a {@link HeaderSet} object. This object can be used to define header values in a request.
	 * 
	 * @return a new {@link HeaderSet} object
	 * @see HeaderSet
	 */
	public HeaderSet createHeaderSet();
	
	/**
	 * Sets the connection ID header to include in the request packets. If a connection ID is 
	 * set, it will be sent in each request to the server except for the CONNECT request. An 
	 * application only needs to set the connection ID if it is trying to operate with 
	 * different targets over the same transport layer connection. If a client receives a 
	 * connection ID from the server, the implementation will continue to use that connection 
	 * ID until the application changes it or until the connection is closed.
	 * 
	 * @param id the connection ID to use
	 * @throws java.lang.IllegalArgumentException if id is not in the range 0 to 2<sup>32</sup>-1
	 */
	public void setConnectionID(long id);
	
	/**
	 * Retrieves the connection ID that is being used in the present connection. This method 
	 * will return -1 if no connection ID is being used.
	 * 
	 * @return the connection ID being used or -1 if no connection ID is being used
	 */
	public long getConnectionID();
	
	/**
	 * Completes an OBEX CONNECT operation. If the {@code headers} argument is {@code null}, 
	 * no headers will be sent in the request. This method will never return {@code null}.
	 * <p>
	 * This method must be called and a successful response code of {@link ResponseCodes#OBEX_HTTP_OK}
	 * must be received before {@link #put(HeaderSet)}, {@link #get(HeaderSet)}, 
	 * {@link #setPath(HeaderSet, boolean, boolean)}, {@link #delete(HeaderSet)},  
	 * or {@link #disconnect(HeaderSet)} may be called. Similarly, after a successful call to 
	 * {@link #disconnect(HeaderSet)}, this method must be called before calling {@link #put(HeaderSet)}, 
	 * {@link #get(HeaderSet)}, {@link #setPath(HeaderSet, boolean, boolean)}, {@link #delete(HeaderSet)}, 
	 * or {@link #disconnect(HeaderSet)}.
	 * 
	 * @param headers the headers to send in the CONNECT request
	 * @return the headers that were returned from the server
	 * @throws java.io.IOException if an error occurred in the transport layer; if the client is 
	 * 				already in an operation; if this method had already been called with a successful 
	 * 				response code of {@link ResponseCodes#OBEX_HTTP_OK} and calls to 
	 * 				{@link #disconnect(HeaderSet)} have not returned a response code of 
	 * 				{@link ResponseCodes#OBEX_HTTP_OK}; if the headers defined in {@code headers} 
	 * 				exceed the max packet length
	 * @throws java.lang.IllegalArgumentException if {@code headers} was not created by a call to 
	 * 				{@link #createHeaderSet()}
	 */
	public HeaderSet connect(HeaderSet headers)
		throws java.io.IOException;
	
	/**
	 * Completes an OBEX DISCONNECT operation. If the headers argument is {@code null}, no headers 
	 * will be sent in the request. This method will end the session. A new session may be started 
	 * by calling {@link #connect(HeaderSet)}. This method will never return {@code null}.

	 * @param headers the header to send in the DISCONNECT request
	 * @return the headers returned by the server
	 * @throws java.io.IOException if an error occurred in the transport layer; if the client is 
	 * 				already in an operation; if an OBEX connection does not exist because 
	 * 				{@link #connect(HeaderSet)} has not been called; if {@link #disconnect(HeaderSet)}
	 *				has been called and received a response code of {@link ResponseCodes#OBEX_HTTP_OK} 
	 *				after the last call to {@link #connect(HeaderSet)}; if the headers defined in 
	 *				{@code headers} exceed the max packet length
	 */
	
	public HeaderSet disconnect(HeaderSet headers)
    	throws java.io.IOException;
    
	/**
	 * Completes an OBEX SETPATH operation. This method will never return {@code null}.
	 * @param headers the headers to include in the SETPATH request
	 * @param backup if {@code true}, instructs the server to back up one directory before moving to 
	 * 					the directory specified in name (similar to cd .. on PCs); if {@code false}, 
	 * 					apply name to the current directory
	 * @param create if {@code true}, instructs the server to create the directory if it does not 
	 * 					exist; if {@code false}, instruct the server to return an error code if the 
	 * 					directory does not exist
	 * @return the headers that were returned from the server
	 * @throws java.io.IOException if an error occurred in the transport layer; if the client is 
	 * 					already in an operation; if an OBEX connection does not exist because 
	 * 					{@link #connect(HeaderSet)} has not been called; if {@link #disconnect(HeaderSet)}
	 * 					had been called and a response code of {@link ResponseCodes#OBEX_HTTP_OK} was 
	 * 					received; if the headers defined in {@code headers} exceed the max packet length
	 * @throws java.lang.IllegalArgumentException if {@code headers} were not created by a call to 
	 * 					{@link #createHeaderSet()}
	 */
	public HeaderSet setPath(HeaderSet headers,
            boolean backup,
            boolean create)
		throws java.io.IOException;
		
	/**
	 * Performs an OBEX DELETE operation. This method will never return {@code null}.
	 * 
	 * @param headers the header to send in the DELETE request
	 * @return the headers returned by the server
	 * @throws java.io.IOException if an error occurred in the transport layer; if the client is 
	 * 					already in an operation; if an OBEX connection does not exist because 
	 * 					{@link #connect(HeaderSet)} has not been called; if {@link #disconnect(HeaderSet)}
	 * 					had been called and a response code of {@link ResponseCodes#OBEX_HTTP_OK} was 
	 * 					received; if the headers defined in {@code headers} exceed the max packet length
	 * @throws java.lang.IllegalArgumentException if {@code headers} were not created by a call to 
	 * 					{@link #createHeaderSet()}
	 */
	public HeaderSet delete(HeaderSet headers)
		throws java.io.IOException;		

	/**
	 * Performs an OBEX GET operation. This method will send the OBEX headers provided to the server 
	 * and return an Operation object to continue with the operation. This method will never 
	 * return {@code null}.
	 *
	 * @param headers the OBEX headers to send as part of the initial GET request
	 * @return the OBEX operation that will complete the GET request
	 * @throws java.io.IOException if an error occurred in the transport layer; if an OBEX connection does 
	 * 					not exist because {@link #connect(HeaderSet)} has not been called; if 
	 * 					{@link #disconnect(HeaderSet)} had been called and a response code of 
	 * 					{@link ResponseCodes#OBEX_HTTP_OK} was received; if {@link #connect(HeaderSet)}
	 * 					has not been called; if the client is already in an operation;
	 * @throws java.lang.IllegalArgumentException if {@code headers} were not created by a call to 
	 * 					{@link #createHeaderSet()}
	 * @see				Operation
	 */
	public Operation get(HeaderSet headers)
		throws java.io.IOException;	
	
	/**
	 * Performs an OBEX PUT operation. This method will send the OBEX headers provided to the server 
	 * and return an {@link Operation} object to continue with the PUT operation. This method will 
	 * never return {@code null}.

	 * @param headers the OBEX headers to send in the initial PUT request
	 * @return the operation object used to complete the PUT request
	 * @throws java.io.IOException if an error occurred in the transport layer; if an OBEX connection does 
	 * 					not exist because {@link #connect(HeaderSet)} has not been called; if 
	 * 					{@link #disconnect(HeaderSet)} had been called and a response code of 
	 * 					{@link ResponseCodes#OBEX_HTTP_OK} was received; if {@link #connect(HeaderSet)}
	 * 					has not been called; if the client is already in an operation;
	 * @throws java.lang.IllegalArgumentException if {@code headers} were not created by a call to 
	 * 					{@link #createHeaderSet()}
	 * @see				Operation
	 */
	public Operation put(HeaderSet headers)
		throws java.io.IOException;
	
}
